package com.hulk.lockd;

import com.hulk.lockd.annotation.EnableLockdConfig;
import com.hulk.lockd.core.BusinessKeyProvider;
import io.netty.channel.nio.NioEventLoopGroup;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import com.hulk.lockd.config.LockdProperties;
import com.hulk.lockd.core.LockInfoProvider;
import com.hulk.lockd.lock.LockFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.util.ClassUtils;

/**
 * Created hulk  on 2019/05/28.
 * Content :lockd自动装配
 * @see klock
 */
@Configuration
@ConditionalOnProperty(prefix = LockdProperties.PREFIX, name = "enable", havingValue = "true", matchIfMissing = true)
@ConditionalOnBean(annotation = EnableLockdConfig.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties(LockdProperties.class)
@Import({LockdInterceptor.class})
public class LockdAutoConfiguration {

    @Autowired
    private LockdProperties lockdProperties;

    @Bean(destroyMethod = "shutdown")
    @ConditionalOnMissingBean
    RedissonClient redisson() throws Exception {
        Config config = new Config();
        if(lockdProperties.getClusterServer()!=null){
            config.useClusterServers().setPassword(lockdProperties.getPassword())
                    .addNodeAddress(lockdProperties.getClusterServer().getNodeAddresses());
        }else {
            config.useSingleServer().setAddress(lockdProperties.getAddress())
                    .setDatabase(lockdProperties.getDatabase())
                    .setPassword(lockdProperties.getPassword());
        }
        Codec codec=(Codec) ClassUtils.forName(lockdProperties.getCodec(),ClassUtils.getDefaultClassLoader()).newInstance();
        config.setCodec(codec);
        config.setEventLoopGroup(new NioEventLoopGroup());
        return Redisson.create(config);
    }

    @Bean
    public LockInfoProvider lockInfoProvider(){
        return new LockInfoProvider();
    }

    @Bean
    public BusinessKeyProvider businessKeyProvider(){
        return new BusinessKeyProvider();
    }

    @Bean
    public LockFactory lockFactory(){
        return new LockFactory();
    }


    @Bean
    public LockdProperties lockdProperties(){
        return new LockdProperties();
    }
    @Bean
    public LockdInterceptor lockdInterceptor(){
        return new LockdInterceptor();
    }

}
